package course.p4_list.s1_OneNextList;

import course.p4_list.List;

/**
 * 单项链表操作类
 */
public class LinkedList implements List {

    /**
     * 头节点
     */
    Node head;
    /**
     * 链表长度
     */
    int size;

    /**
     * 根据头节点计算链表长度
     * @return
     */
    public int calSize() {
        int length = 0;
        Node currentNode = head;
        while (currentNode!=null){
            length++;
            currentNode = currentNode.next;
        }
        size = length;
        return length;
    }

    public int size(){
        return size;
    }


    /**
     * 链表打印
     * @return
     */
    public String toString() {
       Node current = head;
       if(current == null){
          // System.out.println("null");
           return "null";
       }
       StringBuilder stringBuilder = new StringBuilder();
       for(;;){
           //System.out.print(current.getNodeName()+"->");
           stringBuilder.append(current.nodeName).append("->");
           current = current.next;
           if(current == null){
               //System.out.println("null");
               stringBuilder.append("null");
               break;
           }
       }
        return stringBuilder.toString();
    }




    /**
     * 元素插入
     * @param element
     * @param position
     */
    public void insert(int element,int position) {
        // 判断链表内是否存在此位置
        if(position>size||position<0) {
            System.out.println("position 非法, 请检查！");
            return;
        }
        Node newNode = new Node(element,null);
        // 如果链表为空
        if(head == null){
            head = newNode;
            size++;
            return;
        }
        // 在链表头部插入
        if(position == 0){
            newNode.next = head;
        }
        //在链表中间或结尾插入
        else{
            Node previousNode = head;
            int index = 0;
            while (index < position-1) {
                previousNode = previousNode.next;
                index++;
            }
            //进行插入操作
            newNode.next = previousNode.next;
            previousNode.next = newNode;
        }
        size++;
    }

    /**
     * 添加元素
     * @param element 元素
     */
    public void add(int element){
        insert(element,size);
    }

    @Override
    public void addFirst(int element) {

    }


    /**
     * 删除指定位置的元素
     * @param position
     */
    public int remove(int position) {
        int oldEle = -1;
        // 判断链表内是否存在此位置
        if(position>size||position<0) {
            System.out.println("position 非法, 请检查！！");
            return -1;
        }
        if(position == 0){
            head = head.next;
        }
        else{
            Node previousNode = head;
            int index = 0;
            while(index < position-1){
                previousNode = previousNode.next;
                index++;
            }
            //得到要删除的目标节点
            Node currentNode = previousNode.next;
            oldEle = currentNode.data;
            previousNode.next = currentNode.next;
        }
        size--;
        return oldEle;
    }

    @Override
    public void removeFirst(int element) {
        if(head == null) System.out.println("链表为空！！");
        Node cur = head;
        Node pre = null;
        while (cur!=null) {
            if(cur.data == element){
                if(pre==null) head = head.next;
                else{
                    pre.next = cur.next;
                    System.out.println("元素删除完毕！！");
                    break;
                }
            }
            pre = cur;
            cur = cur.next;
        }
    }

    @Override
    public void update(int element, int position) {
        // 如果链表为空
        if(head == null){
            System.out.println("position 非法, 请检查！！");
            return;
        }
        // 判断链表内是否存在此位置
        if(position>size||position<0) {
            System.out.println("position 非法, 请检查！！");
            return;
        }
        // 更新链表头部
        if(position == 0){
            head.data = element;
            //如果在中间或者尾部更新
        }else {
            Node previousNode = head;
            int count = 0;
            while (count < position-1) {
                previousNode = previousNode.next;
                count++;
            }
            //需要后移的元素
            Node currentNode = previousNode.next;
            currentNode.data = element;
            currentNode.nodeName = ""+currentNode.data;
        }
    }

    @Override
    public int get(int position) {
        // 如果链表为空
        if(head == null){
            System.out.println("position 非法, 请检查！！");
            throw new IndexOutOfBoundsException();
        }
        // 判断链表内是否存在此位置
        if(position>size||position<0) {
            System.out.println("position 非法, 请检查！！");
            throw new IndexOutOfBoundsException();
        }
        // 获得链表头部
        if(position == 0){
            return head.data;
            //如果在中间或者尾部插入
        }else {
            Node current = head;
            int count = 0;
            while (count < position) {
                current = current.next;
                count++;
            }
            return current.data;
        }
    }

    /**
     * 链表节点数据结构
     */
      static class Node {
        /**
         * 存储节点数据
         */
        private int data;
        /**
         * 存储下一个节点引用
         */
        private Node next;
        /**
         * 本节点名称
         */
        private String nodeName;
        /**
         * 节点构造方法，仅构造出其存储的数据，并不构造下一节点的引用
         * @param data 节点数据
         */
        public Node(int data, String nodeName) {
            this.data=data;
            if(nodeName==null){
                nodeName=""+data;
            }
            this.nodeName=nodeName;
        }
    }


}
